home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
- "CPCC.C" - A routine to compile a sprite stored in a PCC file
- (C) John Connors 1993
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <mem.h>
- #include <alloc.h>
- #include <string.h>
- #include <stdlib.h>
-
- #define FALSE (0)
- #define TRUE (-1)
-
- /*----------------------------------------------------------------------------
- The header of a .PCX or .PCC file
- ----------------------------------------------------------------------------*/
-
- typedef struct pcc_s
- {
- unsigned char id;
- unsigned char version;
- unsigned char encoding_mode;
- unsigned char bits_per_pixel;
- int x1;
- int y1;
- int x2;
- int y2;
- int horizontal_resolution;
- int vertical_resolution;
- unsigned char colour_map[48];
- unsigned char not_used;
- unsigned char number_of_planes;
- unsigned int bits_per_plane_line;
- unsigned int palette_information;
- unsigned int source_x_resolution;
- unsigned int source_y_resolution;
- unsigned char extra[54];
- } pcc_header; /* pcc_s */
-
- /*----------------------------------------------------------------------------
- Linear bit map header
- ----------------------------------------------------------------------------*/
-
- typedef struct lbm_s
- {
- unsigned int width;
- unsigned int height;
- } lbm_header;
-
- /*----------------------------------------------------------------------------
- Assembler functions callled by cpcc.c
- ----------------------------------------------------------------------------*/
-
- extern unsigned int get_file(char far *file_name,char far *file_buffer);
- extern unsigned int get_file_size(char far *file_name);
-
- extern void decode_pcx_buffer(void far *destination,void far *source);
-
- extern void fix_odd_width_bug(lbm_header *buffer);
-
- extern unsigned int separate_sprite_plane(unsigned char far *source,
- unsigned char far *destination,
- unsigned int plane);
-
- /*----------------------------------------------------------------------------
- Global variable declarations
- ----------------------------------------------------------------------------*/
-
- char far *file_buffer;
- pcc_header far *pcc_buffer;
- lbm_header far *lbm_buffer;
-
- char pcc_name[128];
- char cbm_name[128];
-
- unsigned int pcc_size;
- unsigned int lbm_size;
- unsigned int cbm_size;
-
- unsigned char far *sprite_planes[4];
- unsigned int plane_width[4];
- unsigned int sprite_width;
- unsigned int sprite_height;
- unsigned char far *sprite_byte;
- unsigned int sprite_plane;
-
- unsigned int lbm_width;
- unsigned char far *lbm_byte;
-
- unsigned int si_bump;
-
- unsigned long eax_contents; /* keep track of eax */
- int eax_dirty;
-
- FILE *cbm_file;
-
- /*----------------------------------------------------------------------------
- Remove the file type suffix
- ----------------------------------------------------------------------------*/
-
- char *remove_suffix(char *file_name)
- {
- int l;
- char far *name;
-
- name = strdup(file_name);
- l = strlen(name);
- if ((l>=3) && (name[l-3]=='.'))
- {
- name[l-3] = '\0';
- }
- name = strlwr(name);
- return name;
- } /* remove_suffix() */
-
- /*----------------------------------------------------------------------------
- Open the output file
- ----------------------------------------------------------------------------*/
-
- FILE *open_out(char far *filename)
- {
- FILE *f;
-
- f = fopen(filename,"wt");
-
- if (f==NULL)
- {
- fprintf(stderr,"unable to open %Fs for writing\n",filename);
- exit(0);
- }
-
- fprintf(f,";\n; Compiled Sprite Bitmap \n;\n\n\tIDEAL\n\t\tP386N\n\n");
- fprintf(f,"Map_Mask\t\tEQU\t\t2\n");
- fprintf(f,"Sequencer_Address_Port\t\tEQU\t\t03c4h\n\n");
- fprintf(f,"SEGMENT\t\tCompiled_Sprite_Segment PARA PUBLIC USE16 'CODE'\n");
- fprintf(f,"\t\tASSUME\t\tCS:Compiled_Sprite_Segment\n");
- return f;
- } /* open_out() */
-
-
- /*---------------------------------------------------------------------------
- Emit a 16 bit copy of sprite data to screen
- -----------------------------------------------------------------------------*/
-
- void emit32(unsigned long *value)
- {
- if ((*value != eax_contents) || (eax_dirty))
- fprintf(cbm_file,"\t\tMOV\t\tEAX,0%Flxh\n",*value);
- fprintf(cbm_file,"\t\tSTOSD\n");
- eax_contents = *value;
- eax_dirty = FALSE;
- sprite_byte+=4;
- } /* emit32() */
-
- /*---------------------------------------------------------------------------
- Emit a 16 bit copy of sprite data to screen
- -----------------------------------------------------------------------------*/
-
- void emit16(unsigned int *value)
- {
- eax_dirty = TRUE;
- fprintf(cbm_file,"\t\tMOV\t\tAX,0%Fxh\n",*value);
- fprintf(cbm_file,"\t\tSTOSW\n");
- sprite_byte+=2;
- } /* emit16() */
-
- /*---------------------------------------------------------------------------
- Emit an 8 bit copy of sprite data to screen
- -----------------------------------------------------------------------------*/
-
- void emit8(unsigned char *value)
- {
- eax_dirty = TRUE;
- fprintf(cbm_file,"\t\tMOV\t\tAL,0%Fxh\n",(unsigned int) *value);
- fprintf(cbm_file,"\t\tSTOSB\n");
- sprite_byte++;
- } /* emit8() */
-
- /*---------------------------------------------------------------------------
- Emit an immediate addition to pointer to screen data
- -----------------------------------------------------------------------------*/
-
-
- void emitadd(unsigned int value)
- {
- fprintf(cbm_file,"\t\tADD\t\tDI,0%Fxh\n",value);
- sprite_byte += value;
- lbm_byte += value;
- } /* emitadd() */
-
- /*----------------------------------------------------------------------------
- main procedure
- ----------------------------------------------------------------------------*/
-
- void main(argc,argv)
- int argc;
- char far *argv[];
- {
- int w,h;
-
- w = 0;
- h = 0;
- if (argc!=2)
- {
- fprintf(stderr,"usage :- cpcc <filename>\n");
- exit(0);
- }
- /* ensure .PCC file type */
- strcpy(pcc_name,remove_suffix(argv[1]));
- strcat(pcc_name,".PCC");
- /* ensure .CBM file type */
- strcpy(cbm_name,remove_suffix(argv[1]));
- strcat(cbm_name,".CBM");
-
- /*----------------------------------------------------------------------------
- Read in the .PCC file
- ----------------------------------------------------------------------------*/
-
- pcc_size = get_file_size(pcc_name);
-
- if (pcc_size==0)
- {
- fprintf(stderr,"could not open %Fs.PCC\n",argv[1]);
- exit(0);
- }
-
- file_buffer = farmalloc((unsigned long)pcc_size);
- if (get_file(pcc_name,file_buffer)==0)
- {
- fprintf(stderr,"error reading %Fs.PCC\n",argv[1]);
- exit(0);
- }
-
- /*----------------------------------------------------------------------------
- Copy the .PCC buffer to the linear bit map (lbm) buffer expanding RLE
- ----------------------------------------------------------------------------*/
-
- pcc_buffer = (pcc_header *) file_buffer;
- lbm_size = (pcc_buffer->x2 + 2) *
- (pcc_buffer->y2 + 2);
-
- if ((lbm_buffer = (lbm_header *) farmalloc(lbm_size)) == NULL)
- {
- printf("malloc faliure\n");
- exit(0);
- }
-
- lbm_buffer->width = ((unsigned int) pcc_buffer->x2);
- lbm_buffer->height = ((unsigned int) pcc_buffer->y2);
- decode_pcx_buffer(((unsigned char far *)lbm_buffer)+4,pcc_buffer);
-
- /*----------------------------------------------------------------------------
- Fix the *very* irritating odd width bug in Deluxe Pain(t)
- ----------------------------------------------------------------------------*/
-
- sprite_width = pcc_buffer->x2;
- sprite_height = pcc_buffer->y2;
- /* if ((sprite_width & 1)==0)
- fix_odd_width_bug(lbm_buffer);
- */
-
- /*----------------------------------------------------------------------------
- Create four bit planes
- ----------------------------------------------------------------------------*/
-
- for(sprite_plane=0; sprite_plane<4; sprite_plane++)
- {
- if ((sprite_planes[sprite_plane] = farmalloc(lbm_size)) == NULL)
- {
- fprintf(stderr,"malloc faliure\n");
- exit(0);
- };
- setmem(sprite_planes[sprite_plane],lbm_size,0);
- plane_width[sprite_plane] = separate_sprite_plane( lbm_buffer,
- sprite_planes[sprite_plane],
- sprite_plane );
- }
-
-
- /*----------------------------------------------------------------------------
- Write out assembled instructions to output file
- ----------------------------------------------------------------------------*/
-
- cbm_file = open_out(cbm_name);
-
- fprintf(cbm_file,"\t\tGLOBAL\t%Fs_sprite:FAR\n",remove_suffix(argv[1]));
- fprintf(cbm_file,"\t\tPROC\t\t%Fs_sprite FAR\n",remove_suffix(argv[1]));
- fprintf(cbm_file,"\t\tARG\tVideo_Address:WORD,Plane:WORD =ArgLen\n");
-
- fprintf(cbm_file,"\t\tP386N\n");
- fprintf(cbm_file,"\t\tENTER\t\t0,0\n");
- fprintf(cbm_file,"\t\tPUSH\t\tES\n\t\tPUSH\t\tEDI\n\t\tPUSH\t\tSI\n\t\tPUSH\t\tAX\n");
- fprintf(cbm_file,"\t\tMOV\t\tAX,0a000h\n\t\tMOV\t\tES,AX\n");
- fprintf(cbm_file,"\t\tMOVZX\t\tEDI,[Video_Address]\n");
-
- for(sprite_plane=0;sprite_plane<4;sprite_plane++)
- {
- /* plane by plane */
- fprintf(cbm_file,"; ** plane #%u\n",sprite_plane);
- fprintf(cbm_file,"\t\tMOV\t\tAX,[Plane]\n");
- fprintf(cbm_file,"\t\tMOV\t\tSI,AX\n");
- fprintf(cbm_file,"\t\tMOV\t\tDX,Sequencer_Address_Port\n");
- fprintf(cbm_file,"\t\tMOV\t\tAH,[BYTE CS:@@Map_Mask_Lookup+SI]\n");
- fprintf(cbm_file,"\t\tMOV\t\tAL,Map_Mask\n");
- fprintf(cbm_file,"\t\tOUT\t\tDX,AX\n");
- fprintf(cbm_file,"\t\tPUSH\t\tEDI\n");
- sprite_byte = sprite_planes[sprite_plane];
-
- for(h=0; h<=sprite_height; h++)
- {
- fprintf(cbm_file,"; ROW #%u\n",h);
- w = plane_width[sprite_plane];
- while(w>0)
- {
- if (w>1)
- {
- if (w>3)
- {
- emit32(sprite_byte);
- w -= 4;
- } else
- {
- emit16(sprite_byte);
- w--;
- w--;
- }
- }
- else
- {
- emit8(sprite_byte);
- w--;
- }
- }
-
- if (h != sprite_height)
- {
- fprintf(cbm_file,"\t\tADD\t\tDI,%d\n",
- 80-plane_width[sprite_plane]);
- }
- }
-
- fprintf(cbm_file,"\t\tPOP\t\tEDI\n");
- if (sprite_plane!=3)
- {
- fprintf(cbm_file,"\t\tINC\t\t[Plane]\n");
- fprintf(cbm_file,"\t\tAND\t\t[Plane],3\n");
- fprintf(cbm_file,"\t\tJNZ\t\tSHORT @@%u\n",sprite_plane);
- fprintf(cbm_file,"\t\tINC\t\tEDI\n");
- fprintf(cbm_file,"@@%u:\n",sprite_plane);
- }
- }
- fprintf(cbm_file,"\t\tP386N\n");
- fprintf(cbm_file,"\t\tPOP\t\tAX\n\t\tPOP\t\tSI\n\t\t\n\t\tPOP\t\tEDI\nPOP\t\tES\n");
- fprintf(cbm_file,"\t\tLEAVE\n");
- fprintf(cbm_file,"\t\tRET\t\tArgLen\n");
- fprintf(cbm_file,"@@Map_Mask_Lookup:\n\t\tdb\t01\n\t\tdb\t02\n\t\tdb\t04\n\t\tdb\t08\n");
- fprintf(cbm_file,"ENDP\t\t%Fs_sprite\n",remove_suffix(argv[1]));
- fprintf(cbm_file,"\n\t\tENDS\n");
- fclose(cbm_file);
- printf("Compilation of %Fs done.\n",strupr(cbm_name));
-
- exit(0);
- } /* main() */
-